iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Cloud Native

AWS AI交易室實戰系列 第 10

Day 10 - 使用 Lambda Layer 部署 Python Packages

  • 分享至 

  • xImage
  •  

~ 多了一層,價格不變 ~

AWS Lambda Layer功能使得可以單獨上傳並集中管理Lambda的相依套件了,這樣 Lambda 函數打包的時候就只需要打包該函數本身的程式碼,相依套件只需要引用即可。這樣的好處是顯而易見的:

  1. 開發者不用再關注相依套件,而可以更專注於業務邏輯的開發
  2. 使得函數程式碼變小了,加快了部署的速度,也解除了限制
  3. 可以跨 AWS 帳戶共享程式碼和相依套件,可以通過 Policy 控制與哪些帳戶共享,或者共享給所有帳戶都能分享Layer。

接著我們一步步來示範如何使用 Layer 功能

  • 首先在Docker Container裡面建立 Python 3.7 環境,以下是 Dockerfile 內容
# Day9/marathon-lambda-layer/Dockerfile
FROM amazonlinux:2.0.20191016.0
RUN yum install -y python37 && \
    yum install -y python3-pip && \
    yum install -y zip && \
    yum clean all
RUN python3.7 -m pip install --upgrade pip && \
    python3.7 -m pip install virtualenv
  • 建構 image 然後啟動並進入容器,接著安裝 virtualenv & pandas 套件,最後 zip 起來後退出容器
# Apple M1 Macbook default platform is linux/arm64.
$ docker build --platform=linux/amd64 -t lambdalayer:latest .

# bash into your container.
$ docker run -it --name lambdalayer lambdalayer:latest bash

# in container
bash-4.2# python3.7 -m venv pandas
bash-4.2# source pandas/bin/activate
(pandas) bash-4.2# pip install pandas -t ./python
(pandas) bash-4.2# deactivate
bash-4.2# zip -r layer.zip ./python/
bash-4.2# exit

# in the host
$ docker cp lambdalayer:layer.zip .
  • 直接把 layer.zip 拷貝出來就可以用 AWS CLI 上傳了
$ aws lambda publish-layer-version \
	  --layer-name marathon-layer \
    --description "My First Marathon Layer" \
    --zip-file fileb://layer.zip \
    --compatible-runtimes python3.7 \
    --compatible-architectures "x86_64"
  • 寫個簡單的 lambda_handler.py 並部署上去,先打看看,因為上一步只有上傳並沒有 attach,會有 No module 的 error
# package it to zip format
$ zip function.zip lambda_function.py

# aws cli create-function
# query 'marathon-lambda-ex' role ARN first
$ aws iam get-role --role-name marathon-lambda-ex
$ aws lambda create-function \
--function-name marathon-function-with-layer \
--zip-file fileb://function.zip \
--handler lambda_function.lambda_handler --runtime python3.7 \
--role <marathon-lambda-ex arn>

$ aws lambda invoke --function-name marathon-function-with-layer out.log --log-type Tail

# out.log
{"errorMessage": "Unable to import module 'lambda_function': No module named 'pandas'", "errorType": "Runtime.ImportModuleError", "stackTrace": []}
  • 將 layer attach 上去後再測試看看
$ aws lambda update-function-configuration \
--function-name marathon-function-with-layer \
--layers {layer's $arn:$version} 
# ex. arn:aws:lambda:ap-northeast-1:411932542528:layer:marathon-layer:1

# can query the "last" version layer's arn with layer's name
$ aws lambda list-layer-versions --layer-name {layer name} \
      --max-items 1 --no-paginate --query 'LayerVersions[0].LayerVersionArn' \
      --output text

# test
$ aws lambda invoke --function-name marathon-function-with-layer out.log --log-type Tail

# out.log
{"statusCode": 200, "body": "0    2\n1    1\n2    7\n3    3\ndtype: int64"}

我們可以看到使用 lambda layer 可以部署 python package 上去供 lambda function使用,而lambda function 本身的 package 可以不需要包含這個 package,可以突破 lambda function zip 檔案的 50MB 限制,儘管如此,lambda layer 也有一些限制如下:

  1. 每一個 lambda function 最多只能加入 5 個 layer
  2. 每一個 layer 「解壓縮」後不能超過 250MB
  3. 每一個 layer 的 zip 檔案如果超過 50MB,則必須要先上傳到 S3,再由 create-layer 指定 s3 檔案位置的方式部署
# for the example, need to upload layer.zip to s3 first
$ aws lambda publish-layer-version \
	  --layer-name marathon-layer \
    --description "My First Marathon Layer" \
    --content S3Bucket={Bucket Name},S3Key=layer.zip \
    --compatible-runtimes python3.7 \
    --compatible-architectures "x86_64"
  1. 多個 layer 在 lambda 執行時期解壓縮後統一都會放置到 /opt 這個目錄下面,當有多個 layers,要注意彼此檔案的覆蓋問題

參考資料:

https://medium.com/towards-data-science/how-to-install-python-packages-for-aws-lambda-layer-74e193c76a91
https://dashbird.io/knowledge-base/aws-lambda/lambda-layers/


上一篇
Day 9 - 一天搞定 Docker
下一篇
Day 11 - AWS Lambda with Container Image
系列文
AWS AI交易室實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言